package com.yz.crm.department.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Service;

import com.yz.common.util.IDUtils;
import com.yz.crm.common.dao.CommonDao;
import com.yz.crm.db.dao.BaseDepartmentMapper;
import com.yz.crm.db.model.BaseDepartment;
import com.yz.crm.department.model.Department;
import com.yz.crm.department.service.DepartmentService;
import com.yz.crm.passport.constant.PassportConst;
import com.yz.util.StringUtil;

@Service("departmentService")
@SuppressWarnings({"rawtypes","unchecked"})
public class DepartmentServiceImpl implements DepartmentService {

	@Resource(name="commonDao")
	private CommonDao commonDao;
	
	@Resource
	private SqlSession sqlSession;
	
	@Override
	public BaseDepartment get(String id) {
		return sqlSession.getMapper(BaseDepartmentMapper.class).selectByPrimaryKey(id);
	}
	
	@Override
	public boolean saveOrUpdate(BaseDepartment dept) {
		
		if (dept.getParentId()!=null && dept.getParentId().trim().isEmpty()){
			dept.setParentId(null);
		}
		
		if(dept.getId()==null || dept.getId().isEmpty()){
			dept.setId(IDUtils.getUUID());
			dept.setCreateDate(new Date());
			dept.setModifyDate(dept.getCreateDate());
			sqlSession.getMapper(BaseDepartmentMapper.class).insert(dept);
		}else{
			dept.setModifyDate(new Date());
			sqlSession.getMapper(BaseDepartmentMapper.class).updateByPrimaryKey(dept);
		}
		
		return true;
	}

	/**
	 * 保存
	 * @param dept
	 * @return
	 * @throws Exception
	 */
	public Map<String,Object> save(BaseDepartment dept) throws Exception{
		Map<String,Object> saveMap=new HashMap<String,Object>();
		Date now=new Date();
		int existCode=this.commonDao.count("countExistCode", BaseDepartment.class, dept);
		if(existCode>0){
			saveMap.put(PassportConst.OPER_SUCCESS, false);
			saveMap.put(PassportConst.OPER_MSG, "部门代码已存在,请修改代码");
			return saveMap;
		}
		if(StringUtils.isEmpty(dept.getId())){
			dept.setCreateDate(now);
			dept.setModifyDate(now);
			dept.setId(IDUtils.getObjectId());
			this.commonDao.save(dept);
		}else{
			BaseDepartment dbdept=(BaseDepartment)this.commonDao.load(BaseDepartment.class, dept.getId());
			if(dbdept==null){
				saveMap.put(PassportConst.OPER_SUCCESS, false);
				saveMap.put(PassportConst.OPER_MSG, "保存失败,该部门已被删除");
				return saveMap;
			}
			dept.setModifyDate(now);
			dept.setCreateDate(dbdept.getCreateDate());
			this.commonDao.update(dept);
		}
		Department deptVo=new Department();
		BeanUtils.copyProperties(deptVo, dept);
		saveMap.put(PassportConst.OPER_SUCCESS,true);
		saveMap.put(PassportConst.OPER_MSG,"保存成功");
		saveMap.put("dept",deptVo);
		return saveMap;
	}
	
	/**
	 * 根据公司id列出所有顶层部门
	 * @param companyId
	 * @return
	 */
	@Override
	public List<BaseDepartment> listTopDepartment(String companyId) {
		List<BaseDepartment> departList=this.commonDao.queryForList("listTopDepartmentByCompanyId", BaseDepartment.class, companyId);
	    return departList==null ? new ArrayList<BaseDepartment>() : departList;
	}
	
	/**
	 * 根据部门id,列出部门直属下级id
	 * @param departmentId
	 * @return
	 */
	public List<BaseDepartment> listDirectSub(String departmentId){
		List<BaseDepartment> departList=this.commonDao.queryForList("listDirectSubByDepartmentId", BaseDepartment.class, departmentId);
	    return departList==null ? new ArrayList<BaseDepartment>() : departList;
	}
	
	/**
	 * 根据部门id获取部门所有下级部门
	 * @param departmentId
	 * @return
	 */
	public List<BaseDepartment> listAllSubordinateDept(String departmentId){
		List<BaseDepartment> resultList=new ArrayList<BaseDepartment>();
		recurAllSub(departmentId,resultList);
		return resultList;
	}
	
	/**
	 * 删除部门
	 * @param deptId
	 * @return
	 * @throws Exception
	 */
	public Map<String,Object> delete(String deptId) throws Exception{
		Map<String,Object> deleteMap=new HashMap<String,Object>();
		List<BaseDepartment> empDeptList=new ArrayList<BaseDepartment>();
		findHasEmpDept(deptId,empDeptList);
		if(empDeptList!=null && empDeptList.size()>0){
			BaseDepartment empDept=empDeptList.get(0);
			deleteMap.put(PassportConst.OPER_SUCCESS, false);
			deleteMap.put(PassportConst.OPER_MSG, "部门["+empDept.getName()+"]已经添加员工,删除失败!");
		    return deleteMap;
		}
		recurDelete(deptId);
		deleteMap.put(PassportConst.OPER_SUCCESS, true);
		deleteMap.put(PassportConst.OPER_MSG, "删除成功");
	    return deleteMap;
	}
	
	
	private void recurDelete(String deptId) throws Exception{
		this.commonDao.deleteBySql("deleteById", BaseDepartment.class, deptId);
		List<BaseDepartment> subDeptList=this.listDirectSub(deptId);
		if(subDeptList!=null && subDeptList.size()>0){
			for(BaseDepartment subDept : subDeptList){
				recurDelete(subDept.getId());
			}
		}
	}
	
	/**
	 * 根据部门id获取绑定了员工的部门，每次查询部门及直属下级，获取其中一个有员工的部门即可
	 * @param deptId
	 * @param deptList
	 */
	public void findHasEmpDept(String deptId, List<BaseDepartment> empDeptList){
		BaseDepartment empDept=(BaseDepartment)this.commonDao.queryForObject("findHasEmpById", BaseDepartment.class, deptId);
		if(empDept!=null && !StringUtils.isEmpty(empDept.getId())){
			empDeptList.add(empDept);
			return;
		}else{
			List<BaseDepartment> subDeptList=this.listDirectSub(deptId);
			if(subDeptList!=null && subDeptList.size()>0){
				for(BaseDepartment subDept : subDeptList){
					findHasEmpDept(subDept.getId(),empDeptList);
				}
			}
		}
	}
	
	private void recurAllSub(String departmentId, List<BaseDepartment> resultList){
		List<BaseDepartment> dirSubList=listDirectSub(departmentId);
		if(dirSubList!=null && dirSubList.size()>0){
			for(BaseDepartment dirSub : dirSubList){
				resultList.add(dirSub);
				recurAllSub(dirSub.getId(),resultList);
			}
		}else{
			return;
		}
	}
	
}
